package com.futvan.z.framework.util;

import com.futvan.z.framework.core.z;

import java.math.BigDecimal;
import java.text.ParsePosition;
import java.text.SimpleDateFormat;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.LocalTime;
import java.time.format.DateTimeFormatter;
import java.time.format.DateTimeParseException;
import java.time.temporal.TemporalAccessor;
import java.util.Calendar;
import java.util.Date;
import java.util.Locale;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
/**
 * 日期工具类
 * @author 4223947@qq.com
 *
 */
public class DateUtil {
	public static void main(String[] args) {
		String d = "2023-05-17T18:32:56";
		String df = FormatStringDate(d,"yyyy-MM-dd");
		System.out.println(df);
	}

	/**
	 * 根据出生日期计算年龄
	 * @param birthday
	 * @return
	 */
	public static int getAge(String birthday) {
		return getAge(StringToDate(birthday,"yyyy-MM-dd"));
	}

	/**
	 * 根据出生日期计算年龄
	 * @param birthday
	 * @return
	 */
	public static int getAge(Date birthday) {
		/*从Calendar对象中或得一个Date对象*/
		Calendar cal = Calendar.getInstance();
		/*把出生日期放入Calendar类型的bir对象中，进行Calendar和Date类型进行转换*/
		Calendar bir = Calendar.getInstance();
		bir.setTime(birthday);
		/*取出当前年月日*/
		int yearNow = cal.get(Calendar.YEAR);
		int monthNow = cal.get(Calendar.MONTH);
		int dayNow = cal.get(Calendar.DAY_OF_MONTH);

		/*取出出生年月日*/
		int yearBirth = bir.get(Calendar.YEAR);
		int monthBirth = bir.get(Calendar.MONTH);
		int dayBirth = bir.get(Calendar.DAY_OF_MONTH);
		/*大概年龄是当前年减去出生年*/
		int age = yearNow - yearBirth;
		/*如果出当前月小与出生月，或者当前月等于出生月但是当前日小于出生日，那么年龄age就减一岁*/
		if(monthNow < monthBirth || (monthNow == monthBirth && dayNow < dayBirth)){
			age--;
		}
		if(age<0){
			return 0;
		}else{
			return age;
		}
	}

	/**
	 * 计算时间差[秒]
	 * @param start_time
	 * @param end_time
	 * @return
	 */
	public static String CalcTimeDifference(String start_time,String end_time) {
		String times = "";
		if(z.isNotNull(start_time) && z.isNotNull(end_time)) {
			Date std = StringToDate(start_time,"");
			long st = std.getTime();

			Date etd = StringToDate(end_time,"");
			long et = etd.getTime();

			BigDecimal times_big = (new BigDecimal(et).subtract(new BigDecimal(st))).divide(new BigDecimal(1000),4, BigDecimal.ROUND_DOWN);

			if(times_big.intValue()>=0) {
				times = times_big.intValue()+"";
			}
		}
		return times;

	}

	/**
	 * 获取日期
	 */
	public static String getDate() {
		return getDateTime("yyyy-MM-dd");
	}

	/**
	 * 获取日期时间
	 */
	public static String getDateTime() {
		return getDateTime("yyyy-MM-dd HH:mm:ss");
	}

	/**
	 * 文本日期时间格式化
	 * @param date
	 * @param pattern
	 * @return
	 */
	public static String FormatStringDate(String date, String pattern) {
		String rdate = date;
		if(z.isNotNull(date)) {
			if(z.isNull(pattern)) {
				pattern = "yyyy-MM-dd HH:mm:ss";
			}
			try {
				DateTimeFormatter formatter = DateTimeFormatter.ofPattern(pattern);
				rdate = formatter.format(LocalDateTime.parse(date));

			} catch (DateTimeParseException e) {
				SimpleDateFormat formatter = new SimpleDateFormat(pattern);
				ParsePosition pos = new ParsePosition(0);
				Date strtodate = formatter.parse(date, pos);
				rdate = formatter.format(strtodate);
			} catch (Exception e){
				z.Error("FormatStringDate|日期数据格式化出错|date:"+date+" |pattern: "+pattern, e);
			}
		}
		return rdate;
	}

	/**
	 * 日期格式化
	 *
	 * @param date
	 * @param pattern
	 *            yyyy-MM-dd yyyy-MM-dd HH:mm:ss
	 * @return
	 */
	public static String FormatDate(Object date, String pattern) {
		String rdate = String.valueOf(date);
		if(z.isNotNull(date)){
			if(date instanceof Date) {
				SimpleDateFormat dateformat1 = new SimpleDateFormat(pattern);
				return dateformat1.format(date);
			}else if(date instanceof LocalDateTime){
				LocalDateTime tempdate = (LocalDateTime) date;
				DateTimeFormatter formatter = DateTimeFormatter.ofPattern(pattern);
				rdate = formatter.format(tempdate);
			}else if(date instanceof LocalDate){
				LocalDate tempdate = (LocalDate) date;
				DateTimeFormatter formatter = DateTimeFormatter.ofPattern(pattern);
				rdate = formatter.format(tempdate);
			}else if(date instanceof LocalTime){
				LocalTime tempdate = (LocalTime) date;
				DateTimeFormatter formatter = DateTimeFormatter.ofPattern(pattern);
				rdate = formatter.format(tempdate);
			}
		}
		return rdate;
	}

	/**
	 * 将字符串转换为时间
	 * @param strDate
	 * @param pattern
	 * @return
	 */
	public static Date StringToDate(String strDate,String pattern) {
		if(z.isNull(pattern)) {
			pattern = "yyyy-MM-dd HH:mm:ss";
		}
		SimpleDateFormat formatter = new SimpleDateFormat(pattern);
		ParsePosition pos = new ParsePosition(0);
		Date strtodate = formatter.parse(strDate, pos);
		return strtodate;
	}

	/**
	 * 将日期转为字符串
	 * @param date
	 * @param pattern
	 * @return
	 */
	public static String DateToString(Date date,String pattern) {
		if(z.isNull(pattern)) {
			pattern = "yyyy-MM-dd HH:mm:ss";
		}
		SimpleDateFormat formatter = new SimpleDateFormat(pattern);
		String dateString = formatter.format(date);
		return dateString;
	}

	/**
	 * 获取日期
	 * @param pattern yyyy-MM-dd HH:mm:ss
	 * @return
	 */
	public static String getDateTime(String pattern) {
		LocalDateTime now = LocalDateTime.now();
		DateTimeFormatter formatter = DateTimeFormatter.ofPattern(pattern);
		return now.format(formatter);
	}

	/**
	 * 获取日期-英文
	 * @param pattern "MMM yyyy"
	 * @param locale Locale.UK
	 * @return
	 * getDateTime("MMM yyyy",Locale.UK) 返回 "Mar 2021"
	 */
	public static String getDateTime(String pattern,Locale locale) {
		SimpleDateFormat dateformat1 = new SimpleDateFormat(pattern,locale);
		return dateformat1.format(new java.util.Date());
	}

	/**
	 *
	 * @Title: addDays
	 * @Description: TODO("当前日期后的多少天")
	 * @param @param date
	 * @param @param days
	 * @param @return 设定文件
	 * @return String 返回类型
	 * @throws
	 */
	public static String addYear(String date, int year) {
		return DateAdd(date,"yyyy-MM-dd",Calendar.YEAR,year,null);
	}

	/**
	 * 日期时间加N
	 * @param calendar 加N的类型年、月、日、小时、分
	 * @param n 数量
	 * @return
	 */
	public static String DateAdd(int calendar,int n) {
		return DateAdd(null,null,calendar,n,null);
	}

	/**
	 * 日期时间加N
	 * @param date 日期时间 如果为空默认为当前时间
	 * @param date_pattern 日期时间的标准格式，如果date为空，date_pattern默认为yyyy-MM-dd HH:mm:ss
	 * @param calendar 加N的类型，年、月、日、小时、分
	 * @param n N的数量
	 * @param result_date_pattern 返回日期的格式，如果为空，默认为date_pattern格式
	 * @return
	 */
	public static String DateAdd(String date,String date_pattern,int calendar,int n,String result_date_pattern) {
		String rdate = "";
		try {
			if(z.isNull(date)) {
				date = getDateTime();
				date_pattern = "yyyy-MM-dd HH:mm:ss";
			}else {
				if(z.isNull(date_pattern)) {
					z.Exception("输入的日期时间未定义格式|date_pattern is not null");
				}
			}
			SimpleDateFormat sdf = new SimpleDateFormat(date_pattern);
			Calendar cd = Calendar.getInstance();
			cd.setTime(sdf.parse(date));
			//日期时间加N，calendar为类型，取Calendar类的成员变量
			cd.add(calendar, n);

			//如果result_date_pattern为空
			if(z.isNull(result_date_pattern)) {
				result_date_pattern = date_pattern;
			}
			rdate = sdf.format(cd.getTime());
			//判读是否有返回格式
			if(z.isNotNull(result_date_pattern) && z.isNotNull(rdate)) {
				//格式化返回值
				SimpleDateFormat rdateformat = new SimpleDateFormat(date_pattern);
				rdate = DateToString(rdateformat.parse(rdate), result_date_pattern);
			}
		} catch (Exception e) {
			e.printStackTrace();
		}
		return rdate;
	}




	/**
	 * 判断字符串是否为日期格式
	 * @param strDate
	 * @return
	 */
	public static boolean isDate(String strDate) {
		Pattern pattern = Pattern.compile("^((\\d{2}(([02468][048])|([13579][26]))[\\-\\/\\s]?((((0?[13578])|(1[02]))[\\-\\/\\s]?((0?[1-9])|([1-2][0-9])|(3[01])))|(((0?[469])|(11))[\\-\\/\\s]?((0?[1-9])|([1-2][0-9])|(30)))|(0?2[\\-\\/\\s]?((0?[1-9])|([1-2][0-9])))))|(\\d{2}(([02468][1235679])|([13579][01345789]))[\\-\\/\\s]?((((0?[13578])|(1[02]))[\\-\\/\\s]?((0?[1-9])|([1-2][0-9])|(3[01])))|(((0?[469])|(11))[\\-\\/\\s]?((0?[1-9])|([1-2][0-9])|(30)))|(0?2[\\-\\/\\s]?((0?[1-9])|(1[0-9])|(2[0-8]))))))(\\s(((0?[0-9])|([1-2][0-3]))\\:([0-5]?[0-9])((\\s)|(\\:([0-5]?[0-9])))))?$");
		Matcher m = pattern.matcher(strDate);
		if (m.matches()) {
			return true;
		} else {
			return false;
		}
	}


}
